package com.cal.utms.action.dealing;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.cal.utms.action.user_maintenance.LoginAction;
import com.cal.utms.dao.dealing.DealDao;
import com.cal.utms.dao.dealing.InstrumentDao;
import com.cal.utms.dao.maintenance.InstrumentTypeDao;
import com.cal.utms.dao.user_maintenance.UserDaoImpl;
import com.cal.utms.dto.dealing.PurchaseDealDto;
import com.cal.utms.entity.Deal;
import com.cal.utms.entity.DealInstrumentMap;
import com.cal.utms.entity.Instrument;
import com.cal.utms.entity.InstrumentTransaction;
import com.cal.utms.entity.InstrumentType;
import com.cal.utms.entity.MoneyTransaction;
import com.cal.utms.entity.User;
import com.cal.utms.model.dealing.InstrumentModel;
import com.cal.utms.model.dealing.PurchaseDealModel;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

public class PurchaseDealAction extends ActionSupport implements ModelDriven<PurchaseDealDto> {

	private static final long serialVersionUID = 1L;
	private PurchaseDealDto dealDto = new PurchaseDealDto();

	@Override
	public PurchaseDealDto getModel() {
		return this.dealDto;
	}

	public String getInstrumentCodes() {
		InstrumentDao insDao = new InstrumentDao();
		dealDto.setInstruemtList(insDao.getInstrumentCodes());
		dealDto.setSuccess(true);
		return Action.SUCCESS;
	}

	public String queryDeal() {
		DealDao dealDao = new DealDao();
		PurchaseDealModel pdModel = new PurchaseDealModel();
		Deal deal = dealDao.getById(dealDto.getId());
		if (deal != null) {
			dealDto.getDealDtos().add((pdModel.mapDealToDto(deal)));
			dealDto.setSuccess(true);
		} else {
			dealDto.setStatus("Cannot Find the Deal:" + dealDto.getId());
			dealDto.setSuccess(false);
		}
		return Action.SUCCESS;
	}

	public String queryPurchase() {
		DealDao dealDao = new DealDao();
		if (dealDto.getQuery() != null && !dealDto.getQuery().equals("")) {
			dealDto.setDeals(dealDao.queryDeals("PURCH", dealDto.getQuery()));
		} else {
			dealDto.setDeals(dealDao.queryDeals("PURCH"));
		}
		dealDto.setSuccess(true);
		return Action.SUCCESS;
	}

	public String queryInitPurchase() {
		DealDao dealDao = new DealDao();
		if (dealDto.getQuery() != null && !dealDto.getQuery().equals("")) {
			dealDto.setDeals(dealDao.queryInitDeals("PURCH", dealDto.getQuery()));
		} else {
			dealDto.setDeals(dealDao.queryInitDeals("PURCH"));
		}
		dealDto.setSuccess(true);
		return Action.SUCCESS;
	}

	public String confirmDeal() {
		System.out.println("actioning");
		PurchaseDealModel dealModel = new PurchaseDealModel();
		InstrumentTypeDao insTypeDao = new InstrumentTypeDao();
		InstrumentModel instrumentModel = new InstrumentModel();
		DealDao dealDao = new DealDao();
		InstrumentDao insDao = new InstrumentDao();
		InstrumentType insType = insTypeDao.getById(dealDto.getInsType());
		Deal deal = dealModel.confirmtoToDeal(dealDto, insType);
		deal.setDealCode(dealDto.getDealCode());
		Instrument instrument = instrumentModel.createPurchaseDtoToInstrument(dealDto, insType);
		if (instrument != null) {
			instrument.setStatus("IN");
			Instrument oldInstrument = null;
			if (dealDto.getDealCode() == null) {
				dealDto.setSuccess(false);
				dealDto.setStatus("Cannot Find Deal Code!");
			}
			Deal oldDeal = dealDao.getByCode(dealDto.getDealCode());
			if (oldDeal.getCreatedUser().equals(LoginAction.getCurrentLogingUser().getUserName())) {
				dealDto.setSuccess(false);
				dealDto.setStatus("Created User cannot confirm!");
			}
			if (oldDeal.equals(deal)) {
				System.out.println("deals equal");
				if (insType.getListed() == 0) {
					oldInstrument = insDao.getByCode(dealDto.getInsCode());
				} else {
					oldInstrument = insDao.getByCode(dealDto.getListedInsCode());
				}
				if (oldInstrument == null) {
					dealDto.setSuccess(false);
					dealDto.setStatus("Cannot Find previous Instrument!");
					return Action.SUCCESS;
				} else {
					if (instrument.equals(oldInstrument)) {
						System.out.println("Instruments equal");
						oldDeal.setConfirmedUser(LoginAction.getCurrentLogingUser().getUserName());
						oldDeal.setConfirmedDate(new Date());
						oldDeal.setStatus("Confirmed");

						List<MoneyTransaction> moneyTransactions = new ArrayList<MoneyTransaction>();
						Date today = new Date();
						MoneyTransaction creditEntry = new MoneyTransaction();
						MoneyTransaction debitEntry = new MoneyTransaction();
						User user = new UserDaoImpl().getUserByUsername(LoginAction.getCurrentLogingUser().getUserName());

						creditEntry.setCreditDebit("C");
						if (oldDeal.getSecondaryMarket() == 1) {
							creditEntry.setCustomerType("OUT");
							creditEntry.setTranTo(oldDeal.getId());
						} else if (oldDeal.getIssuer() != null) {
							creditEntry.setCustomerType("ISU");
							creditEntry.setTranTo(oldDeal.getIssuer().getId());
						} else {
							dealDto.setStatus("Cannot Find Issuer for Money Transactions!");
							dealDto.setSuccess(false);
							return Action.SUCCESS;
						}
						creditEntry.setDate(today);
						creditEntry.setEffectDate(oldDeal.getValueDate());
						creditEntry.setFund(oldDeal.getFund());
						creditEntry.setTranAmont(oldDeal.getDealValue());
						creditEntry.setTranType("DEAL");
						creditEntry.setTranTypeId(oldDeal.getId());
						creditEntry.setUser(user);

						debitEntry.setCreditDebit("D");
						if (oldDeal.getFund() != null) {
							debitEntry.setCustomerType("FUN");
							debitEntry.setTranTo(oldDeal.getFund().getId());
						} else {
							dealDto.setStatus("Cannot Find Fund for Money Transactions!");
							dealDto.setSuccess(false);
							return Action.SUCCESS;
						}
						debitEntry.setDate(today);
						debitEntry.setEffectDate(oldDeal.getValueDate());
						debitEntry.setFund(oldDeal.getFund());
						debitEntry.setTranAmont(oldDeal.getDealValue().multiply(new BigDecimal(-1)));
						debitEntry.setTranType("DEAL");
						debitEntry.setTranTypeId(oldDeal.getId());
						creditEntry.setUser(user);
						moneyTransactions.add(creditEntry);
						moneyTransactions.add(debitEntry);

						if (deal.getRolloverShortmaturity() != null && !deal.getRolloverShortmaturity().trim().equals("")) {
							Deal prevDeal = dealDao.getByCode(deal.getRolloverShortmaturity());
							if (prevDeal == null) {
								dealDto.setSuccess(false);
								dealDto.setStatus("Cannot Find Previous Deal");
								return Action.SUCCESS;
							} else if (deal.getFund().getId() != prevDeal.getFund().getId()) {
								dealDto.setSuccess(false);
								dealDto.setStatus("Funds Mismatch. RollOver Failed!");
								return Action.SUCCESS;
							} else if (deal.getValueDate().compareTo(prevDeal.getMaturityDate()) < 0) {
								dealDto.setSuccess(false);
								dealDto.setStatus("Invalid Value Date. RollOver Failed!");
								return Action.SUCCESS;
							} else if (deal.getIssuer().getId() != prevDeal.getIssuer().getId()) {
								dealDto.setSuccess(false);
								dealDto.setStatus("Invalid Issuer. RollOver Failed!");
								return Action.SUCCESS;
							} else {
								prevDeal.setRolloverShortmaturity(deal.getDealCode());
								deal.setDeal(prevDeal);
								deal.setRolloverShortmaturity(null);
							}
						}
						if (oldDeal.getDealInstrumentMaps().get(0) != null && oldDeal.getDealInstrumentMaps().get(0).getInstrument() != null) {
							oldDeal.getDealInstrumentMaps().get(0).getInstrument().setStatus("IN");
						}
						dealDao.confirm(oldDeal, moneyTransactions);
						dealDto.setStatus("OK");
						dealDto.setSuccess(true);
					} else {
						dealDto.setSuccess(false);
						dealDto.setStatus("Instrument Parameter Mismatch!");
						return Action.SUCCESS;
					}
				}
			} else {
				System.out.println("Deals not equal");
				dealDto.setStatus("Deal Parameter Mismatch!");
				dealDto.setSuccess(false);
				return Action.SUCCESS;
			}
		} else {
			dealDto.setSuccess(false);
			dealDto.setStatus("Cannot Find Listed Instrument!");
			return Action.SUCCESS;
		}

		return Action.SUCCESS;
	}

	public String updateDeal() {
		PurchaseDealModel dealModel = new PurchaseDealModel();
		InstrumentModel instrumentModel = new InstrumentModel();
		InstrumentTypeDao insTypeDao = new InstrumentTypeDao();
		DealDao dealDao = new DealDao();
		Deal deal = null;
		Instrument instrument = null;
		// DealInstrumentMap dealInstrumentMap = new DealInstrumentMap();
		// List<InstrumentTransaction> insTrans = new
		// ArrayList<InstrumentTransaction>();
		// dealInstrumentMap.setInstrumentTransactions(insTrans);
		// InstrumentTransaction instrumentTransaction = new
		// InstrumentTransaction();
		InstrumentType insType = insTypeDao.getById(dealDto.getInsType());
		System.out.println("Updating deal...");
		System.out.println(dealDto.getDealCode());
		deal = dealDao.getByCode(dealDto.getDealCode());
		if (deal != null) {
			deal = dealModel.updateDtoToDeal(dealDto, insType, deal);
			instrument = deal.getDealInstrumentMaps().get(0).getInstrument();
			instrument = instrumentModel.updatePurchaseDtoToInstrument(dealDto, insType, instrument);

			dealDao.updatePurchase(deal, instrument, dealDto);
		} else {
			System.out.println("Cannot Find Previous Deal");
		}
		return Action.SUCCESS;
	}

	public String saveDeal() {
		PurchaseDealModel dealModel = new PurchaseDealModel();
		InstrumentModel instrumentModel = new InstrumentModel();
		InstrumentTypeDao insTypeDao = new InstrumentTypeDao();
		DealDao dealDao = new DealDao();
		Deal deal = null;
		Instrument instrument = null;
		DealInstrumentMap dealInstrumentMap = new DealInstrumentMap();
		List<InstrumentTransaction> insTrans = new ArrayList<InstrumentTransaction>();
		dealInstrumentMap.setInstrumentTransactions(insTrans);
		InstrumentTransaction instrumentTransaction = new InstrumentTransaction();
		InstrumentType insType = insTypeDao.getById(dealDto.getInsType());

		System.out.println("Saving deal...");

		System.out.println(dealDto.getMaturityValue());
		deal = dealModel.createDtoToDeal(dealDto, insType);
		instrument = instrumentModel.createPurchaseDtoToInstrument(dealDto, insType);
		instrument.setStatus("PEND");
		dealInstrumentMap.setDeal(deal);
		dealInstrumentMap.setInstrument(instrument);
		dealInstrumentMap.setDate(deal.getCreatedDate());
		// dealInstrumentMap.setStatus(instrument.getStatus());
		dealInstrumentMap.setStatus("Not Received From Customer");
		instrumentTransaction.setStatus("IN");
		instrumentTransaction.setDealInstrumentMap(dealInstrumentMap);
		instrumentTransaction.setDate(dealInstrumentMap.getDate());
		instrumentTransaction.setComment(dealInstrumentMap.getStatus());
		instrumentTransaction.setTransAmount(deal.getDealValue());
		dealInstrumentMap.getInstrumentTransactions().add(instrumentTransaction);
		deal.getDealInstrumentMaps().add(dealInstrumentMap);
		instrument.setLastDeal(deal);
		if (deal.getRolloverShortmaturity() != null && !deal.getRolloverShortmaturity().trim().equals("")) {
			Deal prevDeal = dealDao.getByCode(deal.getRolloverShortmaturity());
			if (prevDeal == null) {
				dealDto.setSuccess(false);
				dealDto.setStatus("Cannot Find Previous Deal");
				return Action.SUCCESS;
			} else if (deal.getFund().getId() != prevDeal.getFund().getId()) {
				dealDto.setSuccess(false);
				dealDto.setStatus("Funds Mismatch. RollOver Failed!");
				return Action.SUCCESS;
			} else if (deal.getValueDate().compareTo(prevDeal.getMaturityDate()) < 0) {
				dealDto.setSuccess(false);
				dealDto.setStatus("Invalid Value Date. RollOver Failed!");
				return Action.SUCCESS;
			} else if (deal.getIssuer().getId() != prevDeal.getIssuer().getId()) {
				dealDto.setSuccess(false);
				dealDto.setStatus("Invalid Issuer. RollOver Failed!");
				return Action.SUCCESS;
			} else {
				prevDeal.setRolloverShortmaturity(deal.getDealCode());
				deal.setDeal(prevDeal);
			}
		}
		System.out.println("Instrument Value:" + instrument.getInstrumentValue());
		Object obj = dealDao.addPurchase(deal, instrument, dealDto);
		if (obj instanceof Number) {
			dealDto.setSuccess(true);
			return Action.SUCCESS;
		} else {
			dealDto.setSuccess(false);
			return Action.SUCCESS;
		}
	}

	public String rejectDeal() {
		if (dealDto.getDealCode() == null) {
			dealDto.setSuccess(false);
			dealDto.setStatus("Deal Code empty!");
			return Action.SUCCESS;
		} else {
			DealDao dealDao = new DealDao();
			Deal deal = dealDao.getByCode(dealDto.getDealCode());
			if (deal == null) {
				dealDto.setSuccess(false);
				dealDto.setStatus("Cannot Find Deal!");
				return Action.SUCCESS;
			} else {
				dealDao.deleteInsTrans(deal);
				InstrumentDao insDao = new InstrumentDao();
				for (DealInstrumentMap dim : deal.getDealInstrumentMaps()) {
					if (dim.getInstrument() != null) {
						dim.getInstrument().setLastDeal(null);
						if (dim.getInstrument().getInstrumentType() != null && dim.getInstrument().getInstrumentType().getListed() == 1) {
							dim.getInstrument().setStatus("Free");
							insDao.setFree(dim.getInstrument());
						} else {
							insDao.delete(dim.getInstrument());
						}
					}
				}
				deal.setModifiedUser(LoginAction.getCurrentLogingUser().getUserName());
				deal.setModifiedDate(new Date());
				deal.setName(deal.getName() + "Rej");
				deal.setStatus("Rejected");
				dealDao.update(deal);
				if (deal.getRolloverShortmaturity() != null && !deal.getRolloverShortmaturity().trim().equals("")) {
					Deal prevDeal = dealDao.getByCode(deal.getRolloverShortmaturity());
					if (prevDeal != null) {
						prevDeal.setRolloverShortmaturity(null);
						dealDao.update(prevDeal);
					}
				}
				dealDto.setSuccess(true);
			}
		}
		return Action.SUCCESS;
	}

	public String valuateDeal() {
		dealDto.setSuccess(true);
		InstrumentTypeDao insTypeDao = new InstrumentTypeDao();
		InstrumentType insType = insTypeDao.getById(dealDto.getInsType());
		if (insType == null) {
			dealDto.setStatus("Cannot Find Instrument Type : " + dealDto.getInsType());
			dealDto.setSuccess(false);
			return Action.SUCCESS;
		}
		PurchaseDealModel pdModel = new PurchaseDealModel();
		pdModel.evaluatePurchase(dealDto, insType);
		return Action.SUCCESS;
	}

	public String valuateDealValue() {
		dealDto.setSuccess(true);
		InstrumentTypeDao insTypeDao = new InstrumentTypeDao();
		InstrumentType insType = insTypeDao.getById(dealDto.getInsType());
		if (insType == null) {
			dealDto.setStatus("Cannot Find Instrument Type : " + dealDto.getInsType());
			dealDto.setSuccess(false);
			return Action.SUCCESS;
		}
		PurchaseDealModel pdModel = new PurchaseDealModel();
		pdModel.evaluatePurchaseDealValue(dealDto, insType);
		return Action.SUCCESS;
	}

}
